<template>
  <div class="home">
    <div class="login">
      <van-nav-bar fixed>
        <van-button
          slot="title"
          round
          type="info"
          size="small"
          class="search-button"
          @click="$router.push('/search')"
          >搜索</van-button>
      </van-nav-bar>
    </div>
    <van-tabs v-model="active">
      <van-tab
        :title="channel.name"
        v-for="channel in channels"
        :key="channel.id"
      >
        <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
          <van-list
            finished-text="没有更多了"
            @load="onLoad(channel)"
            :finished="channel.finished"
            v-model="loading"
          >
          <!-- 在点击传参数的时候 应该把大数字转化成字符串 跳转之后id参数能够识别 -->
            <van-cell
              v-for="item in channel.articles"
              :key="item.art_id.toString()"
              :title="item.title"
              @click="$router.push({
                name: 'article',
                params: {
                  articleId:item.art_id.toString()
                }
              })"
            >
            <!-- 给路由起名字 然后以对象的形式写在路径里 还可以传参数params 可传多个变量参数
                非变量参数 会默认补全 -->
            <!--  之前的写法 @click="$router.push(`/article/${item.art_id}`)" -->
            <div slot="label">
              <van-grid
                :border="false"
                :column-num="3"
                >
                <van-grid-item
                  v-for="img in item.cover.images"
                  :key="img.id"
                >
                  <van-image height="85" lazy-load :src="img" />
                </van-grid-item>
              </van-grid>
              <div class="article-info">
                <span> {{ item.aut_name }} </span>
                <span> {{ item.collect_count }} 评论 </span>
                <span> {{ item.pubdate | relativeTime }} </span>
                <!-- 全局过滤器 -->
              </div>
            </div>
            </van-cell>
          </van-list>
        </van-pull-refresh>
      </van-tab>
      <div slot="nav-right" class="wap-nav" @click="isChannelShow=true">
        <van-icon name="wap-nav"  />
      </div>
    </van-tabs>
    <!-- 频道管理 弹窗 -->
    <van-popup
      v-model="isChannelShow"
      round
      position="bottom"
      :style="{ height: '95%' }"
      closeable
      close-icon-position="top-left"
      @open="onLoadAllChannels"
      @close="isEdit = false"
    >
    <!-- 组件弹出层有自己的事件open 事件触发时再获取所有频道 -->
    <div class="channel-captainer">
      <van-cell title="我的频道" :border="false">
        <van-button
          type="danger"
          size="mini"
          @click="isEdit = !isEdit"
          >
          {{ !isEdit ? '编辑' : '完成' }}</van-button>
      </van-cell>
      <van-grid :gutter="10">
        <!-- 所有的组件如果没有内容的话 可以写单标签
            当有内容时用双标签 -->
        <van-grid-item
          v-for="(channel, index) in channels"
          :key="channel.id"
          :text="channel.name"
          @click="onChannelActiveOrDel(channel, index)"
          >
          <van-icon
            name="close"
            slot="icon"
            v-show="isEdit && channel.name !== '推荐'"
            />
            <!-- 推荐频道不能进行删除 进行判断 在推荐时 不显示x型图标 -->
        </van-grid-item>
      </van-grid>
      <van-cell title="推荐频道" :border="false" />
      <van-grid>
        <van-grid-item
          v-for="channel in recommendChannels"
          :key="channel.id"
          :text="channel.name"
          @click="onAddChannel(channel)"
           />
      </van-grid>
    </div>
    </van-popup>
    <!-- /频道管理 弹窗 -->
  </div>
</template>

<script>
import '@/styles/index.css'
import { getChannels, getAllChannels } from '@/api/channel.js'
import { getArticles } from '@/api/article.js'
import { getItem, setItem } from '@/utils/storage.js'

export default {
  name: 'Home',
  data () {
    return {
      active: 0, // 点击谁 显示的值与索引相同
      channels: [], // 我的频道
      loading: false, // 加载更多
      isLoading: false, // 下拉加载
      isChannelShow: false, // 是否显示弹出层
      allChannels: [], // 所有频道
      isEdit: false // 编辑频道时×型图标 显示条件 默认false
    }
  },
  watch: {
    // 监听我的频道channels数组的数据 当其数据变化时 对其进行本地保存
    channels () {
      setItem('channels', this.channels)
    }
  },
  created () {
    // 加载用户频道
    this.loadChannels()
  },
  computed: {
    // 创建计算属性 根据channels实时计算推荐频道的增加减少
    recommendChannels () {
      const arr = []
      this.allChannels.forEach(channel => {
        // find方法 找到符合条件的第一个项的值 如果没有则返回 undefineda
        const ret = this.channels.find(item => {
          return item.id === channel.id
        })
        if (!ret) {
          arr.push(channel)
        }
      })
      return arr
    }
  },
  methods: {
    async loadChannels () {
      // 定义空数组 等待被赋值
      // 数据持久化之后 通过watch监听channels的变化 并保存到本地
      // 当本地有数据的时候 获取本地 没有的话获取后台数据
      let channels = []
      const localChannels = getItem('channels')
      if (localChannels) {
        channels = localChannels
      } else {
        const res = await getChannels()
        const onlineChannels = res.data.data.channels
        onlineChannels.forEach(channel => {
          channel.articles = []
          channel.finished = false
          channel.tiemstamp = null
        })
        channels = onlineChannels
      }
      // 在未做数据持久化之前
      // const res = await getChannels()
      // console.log(res)
      // const channels = res.data.data.channels
      // // 点击谁加载谁的列表 一个list无法满足这个需求
      // // 频道被遍历的同时 我们希望相对应的文章也被遍历出来
      // // 那么可以在频道数据中添加他自己的文章列表数组 在请求接口之后把对应的文章数据
      // // 放到频道自己的文章列表数组内 之后遍历渲染页面
      // channels.forEach(channel => {
      //   channel.articles = []
      //   // 组件默认绑定同一个finished 那么当第一个加载到没有数据之后 finished被关闭
      //   // 其他的tab栏选项也就显示没有数据了 那么我们需要让每个tab栏有他自己的finished
      //   // 来控制他自己的加载状态
      //   channel.finished = false
      //   channel.timestamp = null // 用于获取频道下一页数据的时间戳
      // })
      this.channels = channels
    },
    async onLoad () {
      // 操作的是tab栏 点击每个tab栏 加载相对应的数据
      // 怎么获取被点击的频道呢 查看channels数组中的数据
      // 得知 tab栏点击后与之数据绑定的active的值和channels对应的频道对象的索引相等
      // 那么this.channels[this.active]即为被点击的那个目标
      const articleChannel = this.channels[this.active]
      // 我们在频道数组中遍历添加了文章列表数组 articles 我们给该数组添加伪数据
      // 验证是否实现点击谁谁加载谁的文章数据 不被点击的处于待点击状态
      const articles = articleChannel.articles
      // 引入获取文章列表方法
      const res = await getArticles({
        channel_id: articleChannel.id,
        timestamp: articleChannel.timestamp || Date.now(),
        with_top: 1
      })
      // 数组添加一个数组 用push方法的话 需要将数组拆分成单项 (...arr) ...为数组展开操作符
      // arr = [] (...arr) = arr[0],arr[1],arr[2]......
      // 下面把获取到的数据放到articles里 遍历该数组
      articles.push(...res.data.data.results)
      // 将loading设置为 false
      this.loading = false
      // 保存目前后台传来的数据中的时间戳 当时间戳为null时 显示数据没有了finished=true
      // 判断下一页的数据 当后台传来的数据中时间戳不为null时 我们更新页面的数据时间戳
      // 当后台数据的时间戳为null时 我们关闭加载 则将 finished 设置为 true
      // 提示没有更多数据了
      const preTimestamp = res.data.data.pre_timestamp
      if (preTimestamp) {
        articleChannel.timestamp = preTimestamp
      } else {
        articleChannel.finished = true
      }

      // setTimeout(() => {
      //   for (let i = 0; i < 10; i++) {
      //   }
      //   // 加载状态结束
      //   // 数据全部加载完成
      //   if (articles.length >= 40) {
      //     articles.finished = true
      //   }
      // }, 500)
    },
    async onRefresh () {
      const articleChannel = this.channels[this.active]
      const res = await getArticles({
        channel_id: articleChannel.id,
        timestamp: Date.now(),
        with_top: 1
      })
      const articles = res.data.data.results
      // 数组再添加数组 需要将数值分解 ...articles
      articleChannel.articles.unshift(...articles)
      this.isLoading = false
      const message = articles.length
        ? `更新了${articles.length}条数据`
        : `暂无数据更新`
      this.$toast(message)
    },
    // 加载所有频道列表
    async onLoadAllChannels () {
      const res = await getAllChannels()
      const allChannels = res.data.data.channels
      allChannels.forEach(channel => {
        channel.articles = []
        channel.finished = false
        channel.tiemstamp = null
      })
      this.allChannels = allChannels
    },
    onAddChannel (channel) {
      this.channels.push(channel)
    },
    onChannelActiveOrDel (channel, index) {
      // 判断按钮是编辑还是完成状态
      if (this.isEdit && channel.name !== '推荐') {
        // 推荐这个选项不能被删除 判断后进行以后操作
        // 为true时是编辑状态 此时显示完成 传入点击的项的索引 通过索引对我的频道数据删除
        // 因为绑定了计算属性 所以此处移除 下方所有频道显示
        this.channels.splice(index, 1)
      } else {
        // 当为false 此时显示编辑 关闭弹出层 并通过active=index 跳转到相应频道
        this.isChannelShow = false
        this.isEdit = false
        this.active = index
      }
    }
  }
}
</script>

<style scoped lang="less">
  .home {
    .search-button {
      width: 100%;
      background-color: #5babfb;
    }
    .van-tabs {
      /deep/ .van-tabs__wrap {
        position: fixed;
        z-index: 2;
        top: 46px;
        left: 0;
        right: 0;
      }
      /deep/ .van-tabs__content {
        margin-top: 90px;
      }
      /deep/ .wap-nav {
        background-color: #fff;
        position: sticky;
        right: 0;
        display: flex;
        align-items:center
      }
    }
    /deep/ .channel-captainer {
      margin-top: 30px;
    }
    /deep/ .van-grid-item__icon-wrapper {
      position: absolute;
      top: -10px;
      right: -5px;
    }
  }
</style>
